using System;
using Coderoom.ScrumPlanner.Data;
using Coderoom.ScrumPlanner.Domain;
using Coderoom.ScrumPlanner.Tests.FakeRepositories;
using Xunit;

namespace Coderoom.ScrumPlanner.Tests.Unit.ServiceTests
{
	public class ThemeServiceTests
	{
		private readonly ThemeService _service;

		public ThemeServiceTests()
		{
			var repository = new FakeThemeRepository();
			_service = new ThemeService(repository);
		}

		[Fact]
		public void GetThemesByProjectId_returns_ThemeCollection()
		{
			// arrange
			var projectId = new Guid("D8185A6C-7145-4751-B149-27B03AB9E5B6");

			// act
			var themes = _service.GetThemes(projectId);

			// assert
			Assert.NotNull(themes);
			Assert.IsType<ThemeCollection>(themes);
			Assert.Equal(2, themes.Count);

			Assert.Equal(new Guid("21FA55C7-CCD5-48D7-B5A9-BB9FD3CE1582"), themes[0].Id);
			Assert.Equal("Theme A", themes[0].Title);
			Assert.Equal("theme-a", themes[0].Slug);

			Assert.Equal(new Guid("AEA523B9-DE70-4660-BD78-2741BFCCFCCA"), themes[1].Id);
			Assert.Equal("Theme B", themes[1].Title);
			Assert.Equal("theme-b", themes[1].Slug);
		}

		[Fact]
		public void GetTheme_returns_Theme_when_theme_is_found()
		{
			// arrange
			var id = new Guid("AEA523B9-DE70-4660-BD78-2741BFCCFCCA");

			// act
			var theme = _service.GetTheme(id);

			// assert
			Assert.NotNull(theme);
			Assert.IsType<Theme>(theme);
			Assert.Equal(id, theme.Id);
			Assert.Equal("Theme B", theme.Title);
			Assert.Equal("theme-b", theme.Slug);
		}

		[Fact]
		public void GetTheme_returns_null_when_theme_is_not_found()
		{
			// arrange
			var id = Guid.Empty;

			// act
			var theme = _service.GetTheme(id);

			// assert
			Assert.Null(theme);
		}

		[Fact]
		public void CreateTheme_returns_void_when_theme_is_created()
		{
			// arrange
			var projectId = new Guid("D8185A6C-7145-4751-B149-27B03AB9E5B6");
			var themes = _service.GetThemes(projectId);
			Assert.Equal(2, themes.Count);

			var newTheme = new Theme();
			newTheme.Title = "Theme C";
			newTheme.Slug = "theme-c";
			newTheme.ProjectId = projectId;

			// act
			_service.CreateTheme(newTheme);

			// assert
			themes = _service.GetThemes(projectId);

			Assert.Equal(3, themes.Count);

			Assert.NotEqual(Guid.Empty, themes[2].Id);
			Assert.Equal("Theme C", themes[2].Title);
			Assert.Equal("theme-c", themes[2].Slug);
			Assert.Equal(projectId, themes[2].ProjectId);
		}

		[Fact]
		public void CreateTheme_throws_ArgumentNullException_when_theme_with_null_title_is_passed()
		{
			// arrange
			var theme = new Theme();

			// act
			Assert.Throws<ArgumentException>(() => _service.CreateTheme(theme));
		}

		[Fact]
		public void CreateTheme_throws_ArgumentException_when_theme_with_empty_title_is_passed()
		{
			// arrange
			var theme = new Theme();
			theme.Title = string.Empty;

			// act
			Assert.Throws<ArgumentException>(() => _service.CreateTheme(theme));
		}

		[Fact]
		public void DeleteTheme_returns_true_when_theme_is_deleted()
		{
			// arrange
			var projectId = new Guid("D8185A6C-7145-4751-B149-27B03AB9E5B6");

			Assert.Equal(2, _service.GetThemes(projectId).Count);

			var id = _service.GetThemes(projectId)[1].Id;

			// act
			var result = _service.DeleteTheme(id);

			// assert
			Assert.True(result);
			Assert.Equal(1, _service.GetThemes(projectId).Count);
		}

		[Fact]
		public void DeleteTheme_returns_false_when_theme_is_not_deleted()
		{
			// arrange
			var projectId = new Guid("D8185A6C-7145-4751-B149-27B03AB9E5B6");

			Assert.Equal(2, _service.GetThemes(projectId).Count);

			var id = Guid.Empty;

			// act
			var result = _service.DeleteTheme(id);

			// assert
			Assert.False(result);
			Assert.Equal(2, _service.GetThemes(projectId).Count);
		}
	}
}